home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / game / think / UChesSrc.lha / genmoves.c < prev    next >
C/C++ Source or Header  |  1993-02-19  |  10KB  |  361 lines

  1. /*
  2.  * genmoves.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback
  5.  * Copyright (c) 1992 Free Software Foundation
  6.  *
  7.  * This file is part of GNU CHESS.
  8.  *
  9.  * GNU Chess is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * GNU Chess is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with GNU Chess; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23. #include "gnuchess.h"
  24. short *TrP;
  25.  
  26. #define Link(from,to,flag,s) \
  27. {\
  28.    node->f = from; node->t = to;\
  29.      node->reply = 0;\
  30.        node->flags = flag;\
  31.      node->score = s;\
  32.        ++node;\
  33.          (*TrP)++;\
  34.          }
  35.  
  36. inline void
  37. LinkMove (ARGSZ int ply, ARGSZ int f,
  38.       ARGSZ int t,
  39.       ARGSZ int flag,
  40.       ARGSZ int xside)
  41.  
  42. /*
  43.  * Add a move to the tree.  Assign a bonus to order the moves as follows: 1.
  44.  * Principle variation 2. Capture of last moved piece 3. Other captures
  45.  * (major pieces first) 4. Killer moves 5.
  46.  */
  47.  
  48. {
  49.   register short s = 0;
  50. #if defined HISTORY
  51.   register short z;
  52. #endif
  53.   register unsigned short mv;
  54.   register struct leaf *node;
  55.  
  56.   node = &Tree[*TrP];
  57.   mv = (f << 8) | t;
  58. #ifdef KILLT
  59.   s += killt[mv | sidebit];
  60. #endif
  61. #ifdef HISTORY
  62.   z = mv;
  63.   if (xside == white) z |= 0x4000;
  64. /*TMPif (z > 32767) { printf("BAD BAD HIST IN GEN1\n");getchar(); }*/
  65.   s += history[z];
  66. #endif
  67.   if (color[t] != neutral)
  68.     {
  69.       /* TOsquare is the square the last piece moved moved to */
  70.       s +=  value[board[t]] - board[f] + ((t == TOsquare) ? 500 : 0);
  71.     }
  72.   if (board[f] == pawn)
  73.     if (row (t) == 0 || row (t) == 7)
  74.       {
  75.     flag |= promote;
  76.     s += 800;
  77. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  78.     Link (f, t, flag | queen, s - 20000);
  79.     s -= 200;
  80.     Link (f, t, flag | knight, s - 20000);
  81.     s -= 50;
  82.     Link (f, t, flag | rook, s - 20000);
  83.     flag |= bishop;
  84.     s -= 50;
  85. #else
  86.     flag |= queen;
  87. #endif
  88.       }
  89.     else if (row (t) == 1 || row (t) == 6)
  90.       {
  91.     flag |= pwnthrt;
  92.     s += 600;
  93.       }
  94.     else if ((row(t) == ((color[f] == white)?5:2)) && (ply > MINDEPTH) && (ply < Sdepth+3))
  95.       {
  96.     if ((mtl[white] - pmtl[white] + mtl[black] - pmtl[black]) < PTVALUE)
  97.       {
  98.         flag |= pwnthrt;
  99.         s += 400;
  100.       }
  101.       }
  102.   Link (f, t, flag, s - 20000);
  103. }
  104.  
  105. inline
  106. void
  107. GenMoves (ARGSZ int ply, ARGSZ int sq, ARGSZ int side, ARGSZ int xside)
  108.  
  109. /*
  110.  * Generate moves for a piece. The moves are taken from the precalulated
  111.  * array nextpos/nextdir. If the board is free, next move is choosen from
  112.  * nextpos else from nextdir.
  113.  */
  114.  
  115. {
  116.   register short u, piece;
  117.   register unsigned char *ppos, *pdir;
  118.  
  119.   TrP = &TrPnt[ply + 1];
  120.   piece = board[sq];
  121.   ppos = nextpos[ptype[side][piece]][sq];
  122.   pdir = nextdir[ptype[side][piece]][sq];
  123.   if (piece == pawn)
  124.     {
  125.       u = ppos[sq];        /* follow no captures thread */
  126.       if (color[u] == neutral)
  127.     {
  128.       LinkMove (ply, sq, u, 0, xside);
  129.       u = ppos[u];
  130.       if (color[u] == neutral)
  131.         LinkMove (ply, sq, u, 0, xside);
  132.     }
  133.       u = pdir[sq];        /* follow captures thread */
  134.       if (color[u] == xside)
  135.     LinkMove (ply, sq, u, capture, xside);
  136.       u = pdir[u];
  137.       if (color[u] == xside)
  138.     LinkMove (ply, sq, u, capture, xside);
  139.     }
  140.   else
  141.     {
  142.       u = ppos[sq];
  143.       do
  144.     {
  145.       if (color[u] == neutral)
  146.         {
  147.           LinkMove (ply, sq, u, 0, xside);
  148.           u = ppos[u];
  149.         }
  150.       else
  151.         {
  152.           if (color[u] == xside)
  153.         LinkMove (ply, sq, u, capture, xside);
  154.           u = pdir[u];
  155.         }
  156.       } while (u != sq);
  157.     }
  158. }
  159.  
  160. void
  161. MoveList (INTSIZE int side, INTSIZE int ply)
  162.  
  163. /*
  164.  * Fill the array Tree[] with all available moves for side to play. Array
  165.  * TrPnt[ply] contains the index into Tree[] of the first move at a ply.
  166.  */
  167.  
  168. {
  169.   register short i, xside, f;
  170.  
  171.   xside = side ^ 1;
  172.   TrP = &TrPnt[ply + 1];
  173.   *TrP = TrPnt[ply];
  174.   if (!PV)
  175.     Swag0 = killr0[ply];
  176.    else Swag0 = PV;
  177.   Swag1 = killr1[ply];
  178.   Swag2 = killr2[ply];
  179.   Swag3 = killr3[ply];
  180.   if (ply > 2)
  181.     Swag4 = killr1[ply - 2]; else Swag4 = 0;
  182. #ifdef KILLT
  183.   sidebit = ((side == white) ? 0 : 0x80);
  184.   killt[SwagHt | sidebit] += 5000;
  185.   killt[Swag0 | sidebit] += 2000;
  186.   killt[Swag1 | sidebit] += 60;
  187.   killt[Swag2 | sidebit] += 50;
  188.   killt[Swag3 | sidebit] += 40;
  189.   killt[Swag4 | sidebit] += 30;
  190. #endif
  191. #ifdef HISTORY
  192.   i = (side == black)?0x4000:0;
  193. /*TMPif ((SwagHt | i) > 32767) { printf("BAD BAD HIST IN GEN2\n");getchar(); }*/
  194.   history[SwagHt | i] += 5000;
  195. /*TMPif ((Swag0 | i) > 32767) { printf("BAD BAD HIST IN GEN3\n");getchar(); }*/
  196.   history[Swag0 | i] += 2000;
  197. /*TMPif ((Swag1 | i) > 32767) { printf("BAD BAD HIST IN GEN4\n");getchar(); }*/
  198.   history[Swag1 | i] += 60;
  199. /*TMPif ((Swag2 | i) > 32767) { printf("BAD BAD HIST IN GEN5\n");getchar(); }*/
  200.   history[Swag2 | i] += 50;
  201. /*TMPif ((Swag3 | i) > 32767) { printf("BAD BAD HIST IN GEN6\n");getchar(); }*/
  202.   history[Swag3 | i] += 40;
  203. /*TMPif ((Swag4 | i) > 32767) { printf("BAD BAD HIST IN GEN7\n");getchar(); }*/
  204.   history[Swag4 | i] += 30;
  205. #endif
  206.   for (i = PieceCnt[side]; i >= 0; i--)
  207.     GenMoves (ply, PieceList[side][i], side, xside);
  208.   if (!castld[side])
  209.     {
  210.       f = PieceList[side][0];
  211.       if (castle (side, f, f + 2, 0))
  212.     {
  213.       LinkMove (ply, f, f + 2, cstlmask, xside);
  214.     }
  215.       if (castle (side, f, f - 2, 0))
  216.     {
  217.       LinkMove (ply, f, f - 2, cstlmask, xside);
  218.     }
  219.     }
  220.   if (epsquare > 0)
  221.     {
  222.       f = epmove1[epsquare];
  223.       if (color[f] == side && board[f] == pawn)
  224.     LinkMove (ply, f, epsquare, capture | epmask, xside);
  225.       f = epmove2[epsquare];
  226.       if (color[f] == side && board[f] == pawn)
  227.     LinkMove (ply, f, epsquare, capture | epmask, xside);
  228.     }
  229. #ifdef KILLT
  230.   killt[SwagHt | sidebit] -= 5000;
  231.   killt[Swag0 | sidebit] -= 2000;
  232.   killt[Swag1 | sidebit] -= 60;
  233.   killt[Swag2 | sidebit] -= 50;
  234.   killt[Swag3 | sidebit] -= 40;
  235.   killt[Swag4 | sidebit] -= 30;
  236. #endif
  237. #ifdef HISTORY
  238.  i = (side == black)?0x4000:0;
  239. /*TMPif ((SwagHt | i) > 32767) { printf("BAD BAD HIST IN GEN8\n");getchar(); }*/
  240.   history[SwagHt | i] -= 5000;
  241. /*TMPif ((Swag0 | i) > 32767) { printf("BAD BAD HIST IN GEN9\n");getchar(); }*/
  242.   history[Swag0 | i] -= 2000;
  243. /*TMPif ((Swag1 | i) > 32767) { printf("BAD BAD HIST IN GEN10\n");getchar(); }*/
  244.   history[Swag1 | i] -= 60;
  245. /*TMPif ((Swag2 | i) > 32767) { printf("BAD BAD HIST IN GEN11\n");getchar(); }*/
  246.   history[Swag2 | i] -= 50;
  247. /*TMPif ((Swag3 | i) > 32767) { printf("BAD BAD HIST IN GEN12\n");getchar(); }*/
  248.   history[Swag3 | i] -= 40;
  249. /*TMPif ((Swag4 | i) > 32767) { printf("BAD BAD HIST IN GEN13\n");getchar(); }*/
  250.   history[Swag4 | i] -= 30;
  251. #endif
  252.   SwagHt = 0;            /* SwagHt is only used once */
  253.   GenCnt += (TrPnt[ply+1] - TrPnt[ply]);
  254. }
  255.  
  256. void
  257. CaptureList (INTSIZE int side, INTSIZE int ply)
  258.  
  259. /*
  260.  * Fill the array Tree[] with all available cature and promote moves for side
  261.  * to play. Array TrPnt[ply] contains the index into Tree[] of the first move
  262.  * at a ply.
  263.  */
  264.  
  265. {
  266.   register short u, sq, xside;
  267.   register struct leaf *node;
  268.   register unsigned char *ppos, *pdir;
  269.   short i, piece, *PL, r7;
  270.  
  271.   xside = side ^ 1;
  272.   TrP = &TrPnt[ply + 1];
  273.   *TrP = TrPnt[ply];
  274.   node = &Tree[*TrP];
  275.   r7 = rank7[side];
  276.   PL = PieceList[side];
  277. #ifdef KILLT
  278.   sidebit = ((side == white) ? 0 : 0x80);
  279.   killt[SwagHt | sidebit] += 5000;
  280.   killt[Swag0 | sidebit] += 2000;
  281.   killt[Swag1 | sidebit] += 60;
  282.   killt[Swag2 | sidebit] += 50;
  283.   killt[Swag3 | sidebit] += 40;
  284.   killt[Swag4 | sidebit] += 30;
  285. #endif
  286.  
  287.   for (i = 0; i <= PieceCnt[side]; i++)
  288.     {
  289.       sq = PL[i];
  290.       piece = board[sq];
  291.       if (sweep[piece])
  292.     {
  293.       ppos = nextpos[piece][sq];
  294.       pdir = nextdir[piece][sq];
  295.       u = ppos[sq];
  296.       do
  297.         {
  298.           if (color[u] == neutral)
  299.         u = ppos[u];
  300.           else
  301.         {
  302.           if (color[u] == xside)
  303.             Link (sq, u, capture, value[board[u]] + svalue[board[u]] - piece);
  304.           u = pdir[u];
  305.         }
  306.       } while (u != sq);
  307.     }
  308.       else
  309.     {
  310.       pdir = nextdir[ptype[side][piece]][sq];
  311.       if (piece == pawn && row (sq) == r7)
  312.         {
  313.           u = pdir[sq];
  314.           if (color[u] == xside)
  315.         Link (sq, u, capture | promote | queen, valueQ);
  316.           u = pdir[u];
  317.           if (color[u] == xside)
  318.         {
  319.           Link (sq, u, capture | promote | queen, valueQ);
  320. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  321.           Link (sq, u, capture | promote | knight, valueN);
  322.           Link (sq, u, capture | promote | rook, valueR);
  323.           Link (sq, u, capture | promote | bishop, valueB);
  324. #endif
  325.         }
  326.           ppos = nextpos[ptype[side][piece]][sq];
  327.           u = ppos[sq];    /* also generate non capture promote */
  328.           if (color[u] == neutral)
  329.         {
  330.           Link (sq, u, promote | queen, valueQ);
  331. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  332.           Link (sq, u, promote | knight, valueN);
  333.           Link (sq, u, promote | rook, valueR);
  334.           Link (sq, u, promote | bishop, valueB);
  335. #endif
  336.         }
  337.         }
  338.       else
  339.         {
  340.           u = pdir[sq];
  341.           do
  342.         {
  343.           if (color[u] == xside)
  344.             Link (sq, u, capture, value[board[u]] + svalue[board[u]] - piece);
  345.           u = pdir[u];
  346.           } while (u != sq);
  347.         }
  348.     }
  349.     }
  350. #ifdef KILLT
  351.   sidebit = ((side == white) ? 0 : 0x80);
  352.   killt[SwagHt | sidebit] -= 5000;
  353.   killt[Swag0 | sidebit] -= 2000;
  354.   killt[Swag1 | sidebit] -= 60;
  355.   killt[Swag2 | sidebit] -= 50;
  356.   killt[Swag3 | sidebit] -= 40;
  357.   killt[Swag4 | sidebit] -= 30;
  358. #endif
  359.   SwagHt = 0;            /* SwagHt is only used once */
  360. }
  361.